// Upgrades.cs
//

using System;
using System.Collections.Generic;
using System.Html;
using System.Diagnostics;

namespace TuringMachine
{
   public class Upgrades
   {
      public Upgrades(string upgString)
      {
         m_activeUpgrades = new Dictionary<string, bool>();
         foreach (string key in upgString.Split(','))
            SetUpgrade(key, true);
      }

      private Dictionary<string, bool> m_activeUpgrades;

      public bool HasUpgrade(string key)
      {
         return m_activeUpgrades[key];
      }

      public string GetUpgradeString()
      {
         string upgString="";
         foreach (string key in m_activeUpgrades.Keys)
         {
            if (m_activeUpgrades[key])
            {
               if (upgString != "") upgString += ",";
               upgString += m_activeUpgrades.Keys;
            }
         }
         return upgString;
      }

      public void SetUpgrade(string key, bool value)
      {
         if (value)
            m_activeUpgrades[key] = true;
         else
            m_activeUpgrades.Remove(key);
      }

      public bool pStepEnabled
      {
         get { return m_activeUpgrades[KEY_STEP]; }
         set { SetUpgrade(KEY_STEP,value); }
      }

      public bool pDebugEnabled
      {
         get { return m_activeUpgrades[KEY_DEBUG]; }
         set { SetUpgrade(KEY_DEBUG,value); }
      }

      public bool pExtendedSize
      {
         get { return m_activeUpgrades[KEY_EXTSIZE]; }
         set { SetUpgrade(KEY_EXTSIZE,value); }
      }

      public bool pSelectionEnabled
      {
         get { return m_activeUpgrades[KEY_SELECTION]; }
         set { SetUpgrade(KEY_SELECTION,value); }
      }

      public bool pSaveLoadSelectionEnabled
      {
         get { return m_activeUpgrades[KEY_SELSAVELOAD]; }
         set { SetUpgrade(KEY_SELSAVELOAD,value); }
      }
      public bool pOpSwapValueEnabled
      {
         get { return m_activeUpgrades[KEY_SWAP]; }
         set { SetUpgrade(KEY_SWAP,value); }
      }
      public bool pDoubleMovementEnabled
      {
         get { return m_activeUpgrades[KEY_DOUBLEMOV]; }
         set { SetUpgrade(KEY_DOUBLEMOV,value); }
      }
      public bool pRedDotEnabled
      {
         get { return m_activeUpgrades[KEY_REDDOT]; }
         set { SetUpgrade(KEY_REDDOT,value); }
      }
      public bool pTwoTapesEnabled
      {
         get { return m_activeUpgrades[KEY_TWOTAPES]; }
         set { SetUpgrade(KEY_TWOTAPES,value); }
      }
      public bool pOpWriteValueFromOtherEnabled
      {
         get { return m_activeUpgrades[KEY_WRITEVAL]; }
         set { SetUpgrade(KEY_WRITEVAL,value); }
      }
      public bool pOpCompareEnabled
      {
         get { return m_activeUpgrades[KEY_COMPARE]; }
         set { SetUpgrade(KEY_COMPARE,value); }
      }
      public bool pOpFunctionEnabled
      {
         get { return m_activeUpgrades[KEY_FUNCTION]; }
         set { SetUpgrade(KEY_FUNCTION,value); }
      }
      public bool pOpInsertEnabled
      {
         get { return m_activeUpgrades[KEY_INSERT]; }
         set { SetUpgrade(KEY_INSERT,value); }
      }
      public bool pOpRemoveEnabled
      {
         get { return m_activeUpgrades[KEY_REMOVE]; }
         set { SetUpgrade(KEY_REMOVE,value); }
      }
      public bool pColorizeEnabled
      {
         get { return m_activeUpgrades[KEY_COLORIZE]; }
         set { SetUpgrade(KEY_COLORIZE, value); }
      }

      public const string KEY_STEP = "Step";
      public const string KEY_DEBUG = "Debug";
      public const string KEY_EXTSIZE = "ExtendedSize";
      public const string KEY_SELECTION = "Selection";
      public const string KEY_SELSAVELOAD = "SaveLoadSelection";
      public const string KEY_SWAP = "SwapValue";

      public const string KEY_DOUBLEMOV = "DoubleMovement";
      public const string KEY_REDDOT = "RedDot";
      public const string KEY_TWOTAPES = "TwoTapes";
      public const string KEY_WRITEVAL = "WriteValueFromOther";
      public const string KEY_COMPARE = "Compare";
      public const string KEY_FUNCTION = "Function";

      public const string KEY_INSERT = "Insert";
      public const string KEY_REMOVE = "Remove";
      public const string KEY_COLORIZE = "Colorize";

   }

   public class UpgradeList
   {
      public static List<Upgrade> m_lAllUpgrades;
      static UpgradeList()
      {
         m_lAllUpgrades = new List<Upgrade>();
         m_lAllUpgrades.Add(new Upgrade("Debug", "Debug", "Allows you to debug your machine, change the tape values and change the starting point", 20));
         m_lAllUpgrades.Add(new Upgrade("Step", "Step", "Allows you to debug your machine step by step", 20));
         m_lAllUpgrades.Add(new Upgrade("ExtendedSize", "Bigger board", "Enlarges the space for your machine giving you more than twice the original size", 35));
         m_lAllUpgrades.Add(new Upgrade("Selection", "Block selection", "Enables the use of block operations such as move, copy and delete", 25));
         m_lAllUpgrades.Add(new Upgrade("SaveLoadSelection", "Block storage", "Allows you to save and load parts of your machine", 15));
         m_lAllUpgrades.Add(new Upgrade("SwapValue", "Switcher", "Adds a new operation type which switches the current value of the tape from 0 to 1 and vice versa", 20));

         m_lAllUpgrades.Add(new Upgrade("DoubleMovement", "Jumper", "Enables jumping over adjacent cells", 30));
         m_lAllUpgrades.Add(new Upgrade("RedDot", "Red dot", "Adds a new value that can be used in all operations and behaves like the other values (zero, one or the green dot)", 50));
         m_lAllUpgrades.Add(new Upgrade("TwoTapes", "Additional tape", "Adds a new tape which you can use to store temporary information.", 75));
         m_lAllUpgrades.Add(new Upgrade("WriteValueFromOther", "Copier", "Creates a new operation type which allows you to copy values between tapes", 55));
         m_lAllUpgrades.Add(new Upgrade("Compare", "Comparer", "Creates a new operation type which allows you to compare values between tapes", 45));
         m_lAllUpgrades.Add(new Upgrade("Function", "Function", "Adds the possibility of repeating parts of the machine at different stages of the execution", 100));

         m_lAllUpgrades.Add(new Upgrade("Insert", "Inserter", "Adds a new operation which allows you to insert new values in the tape", 50));
         m_lAllUpgrades.Add(new Upgrade("Remove", "Remover", "Adds a new operation which removes values from the tape", 40));
         m_lAllUpgrades.Add(new Upgrade("Colorize", "Colorize", "Allows you to change the colors of individual cells in the board. Note that you need 'Block selection' upgrade too", 5));

         int totalCredit = 0;
         foreach (Upgrade c in m_lAllUpgrades) totalCredit += c.m_iCredits;
         Debug.WriteLine("Upgrade count :" + m_lAllUpgrades.Count.ToString() + "\nCredits :" + totalCredit);
      }
   }

   public class Upgrade
   {
      public string m_sDescription;
      public int m_iCredits;
      public string m_sKey;
      public string m_sName;

      public Upgrade(string sKey, string sName, string desc, int credits)
      {
         m_sKey = sKey;
         m_sName = sName;
         m_sDescription = desc;
         m_iCredits = credits;
      }
   }
}
